<%-- 
   * 【描 述】：通讯
   * 【环 境】：JAVA 1.7.0_13
   *  @author         柴志鹏  CHAIZP@GMAIL.COM
   *  @version        v1.0 2014-09
   *  @since          2014-09
 --%>
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@ include file="/include/head.jsp"%>
<html>
	<head>
		<title>Instant Messaging</title>
		<meta http-equiv="content-type" content="text/html;charset=UTF-8">
		<script src="ajax-pushlet-client.js" type="text/javascript"></script>
		<script type="text/javascript">
//获取id为"im-win"的window窗口
var im = parent.MyDesktop.getDesktop().getWindow("im-win");
var flag = false;
im.on('beforeclose', function(panel) {//定义win关闭前事件
	if(!flag) {
		//判断聊天窗口是否全部隐藏
		if(flag = (hideWinCount == 0)) {
			for(var i = 0; i < OpenedWin.length; i++) {
				//关闭全部隐藏聊天窗口
				parent.Ext.getCmp(OpenedWin[i]).close();
			}
		}
	}
	if(!flag) {
		parent.Ext.MessageBox.show({
			title: '关闭会话通讯',
			msg: '确定关闭所有通讯窗口?',
			modal: false,//模态
			buttons: Ext.Msg.YESNO,
			fn: function(id, msg) {
				if(id == 'yes') {
					for(var i = 0; i < OpenedWin.length; i++) {
						//关闭全部已开启聊天窗口
						parent.Ext.getCmp(OpenedWin[i]).close();
					}
					flag = true;
					im.close();
				}
			}
		});
	}
	return flag;
});


Ext.onReady(function() {
	Ext.QuickTips.init();
	Ext.form.Field.prototype.msgTarget = 'qtip';
	//非debug模式
	PL.setDebug(false);
	//在线用户  里面装的就是树节点（的引用）
	onlines = new Array();

	var viewport = new Ext.Viewport({
   		layout: 'fit',
		items: [
			new Ext.tree.TreePanel({
				id: 'im-tree',
				title: 'Online Users',
				loader: new Ext.tree.TreeLoader(),
				rootVisible: false,
				lines: false,
				autoScroll: true,
				root: new Ext.tree.AsyncTreeNode( {
					text: 'Online',
					children: []
				}),
				listeners: {
					'dblclick': function(node) {
						showChatWindow(node);
					}
				}
			})
		]
	});
	PL.joinListen('/pushlet/ping,/user/login,/user/chat');
});

function onEvent(event) {
	//如果是登陆的消息 并且不是自己发出的 并且 树中没有这个id的节点
	if (event.getSubject() == '/user/login'//登录
			//&& PL.sessionId != event.get('p_from')
			&& Ext.getCmp('im-tree').getNodeById(event.get('p_from')) == null) {//Tree中没有此节点
		//就添加节点
		var node4add = new Ext.tree.TreeNode({
			id: event.get('p_from'),
			text: decodeURIComponent(event.get('name')),
			iconCls: 'user',
			leaf: true
		});
		//给节点添加一个时间戳属性，以后用来判断是否在线  这个属性会不断刷新  长时间不刷新就说明掉了
		node4add.aliveTS = event.get('p_time');
		//将节点添加到Tree中
		Ext.getCmp('im-tree').root.appendChild(node4add);
		//添加到在线数组中
		onlines.push(node4add);
	} else if(event.getSubject() == '/user/login' //登录
			&& PL.sessionId != event.get('p_from')//登录人不是自己
			&& Ext.getCmp('im-tree').getNodeById(event.get('p_from')) != null ) {//Tree中有此节点
		//如果是登陆的消息 并且不是自己发出的 并且 树中有这个id的节点  就更新他的在线时间戳
		Ext.getCmp('im-tree').getNodeById(event.get('p_from')).aliveTS=event.get('p_time');
	}
	//如果是聊天的信息   
	if (event.getSubject() == '/user/chat') {
		var node = Ext.getCmp('im-tree').getNodeById(event.get('p_from'));
		//打开聊天窗口
		showChatWindow(node);
		var now = new Date();
		var time = " "+ now.getHours() +":"+ now.getMinutes() +":"+ now.getSeconds();
		//解码回车符  消息在发送的时候对回车符进行了替换 现在替换回来 否则在经过服务器的时候回车符会丢失
		var smessage = event.get('message');
		//var reg = new RegExp(PL.sessionId, 'g'); //创建正则RegExp对象
		//smessage = smessage.replace(reg, '\n');
		//把新消息添加到历史信息栏
		var ShowMessage = "<span style='color:blue;font-weight:bold;font-size:12'>" + node.text 
				+ "</span><span style='color:blue'>" + '     ' + time 
				+ '</span><br/>' + decodeURIComponent(smessage) + '<br/>';
		parent.Ext.get('cw_hw_' + node.id).dom.innerHTML += ShowMessage;
		//Ext.get('cw_hw_' + node.id).dom.value += node.text + '  ' + time + '   \n' + smessage + '\n\n';
		//Ext.getCmp('cw_hw_' + node.id).setValue(Ext.getCmp('cw_hw_' + node.id).getValue() 
		//	+ node.text + '  ' + time + '   <br/>' + smessage + '<br/><br/>');
		//让滚动条始终保持在最下方
		var hwDom = parent.Ext.get('cw_hw_' + node.id).dom;
		hwDom.scrollTop = hwDom.scrollHeight - hwDom.offsetHeight;
	}
}

//借助一定周期的RefreshAck事件  发送我的在线信息  
 //是为了提供给刚上线的user 并监控在线用户的时间戳是否较新  否则判断为掉线 踢掉
 //Refresh是为了让服务器知道client没死
function onRefreshAck(event) {
	for(var i=0;i<onlines.length;i++) {
		//获得节点 Id
		var curNode = Ext.getCmp('im-tree').root.item(i);
		//当不是自己的时候
		if(curNode.id != PL.sessionId) {
			//当前时间戳-上次更新的时间戳 如果间隔较大 说明没更新  掉了
			if((event.get('p_time') - onlines[i].aliveTS) > 15){
				var t = new Ext.ToolTip({
					target: 'mainUI',
					dismissDelay: 15000 ,
					html: onlines[i].text+'离开了'
				});
				t.showAt([50,80]);
				onlines[i].remove();//从树上移除
				onlines.remove(onlines[i]);//从在线用户移除
			}
		}
	}
	publish();
}
//发布上线信息
function publish() {
	PL.publish('/user/login', 'name=' + encodeURIComponent(encodeURIComponent(c_getUsername())));//解决神奇的中文名称导致pushlet挂掉
}

//已打开的聊天窗口
var OpenedWin = new Array();
//被隐藏的聊天窗口
var hideWinCount = 0;
//打开聊天窗口
function showChatWindow(node) {
	var chatwindow = parent.Ext.getCmp('cw_' + node.id);//如果在父窗口中打开此句要是忘加parent.那会very high...
	if (chatwindow == null) {
		OpenedWin.push('cw_' + node.id);
		chatwindow = new parent.Ext.Window({
			renderTo: 'x-desktop',//渲染到指定div
			id: 'cw_' + node.id,
			title: node.text,
			layout: 'anchor',
			width: 400,
			height: 465,
			bodyStyle: 'padding:0px;',
			draggable: true,//可拖动
			closable: true,
			closeAction: 'hide',
			maximizable: true,
			//constrain: true,//禁止窗口移出浏览器
			constrainHeader: true,//禁止标头移出浏览器
			plain: false,
			modal: false,
			resizable: true,//可调整大小
			x: 400 + onlines.indexOf(node) * 30,
			y: 100,
			listeners: {
				'resize': function(win, width, height) {
					parent.Ext.getCmp('cw_hw_' + node.id).setHeight(height-163);
				},
				'hide': function(win) {
					hideWinCount--;//点击窗体关闭按钮时数量-1
				},
				'show': function(win) {
					hideWinCount++;//开启聊天窗口时数量+1
				}
			},
			items: [
				new parent.Ext.form.FormPanel({
					//frame: false,
					autoHeight: true,
					bodyStyle: 'padding:0px',
					border: false,
					items: [
						new parent.Ext.BoxComponent({
							id: 'cw_hw_' + node.id,
							hideLabel: true,
							readOnly: true,
							name: 'box',
							height: 300,
							bodyStyle: 'padding:0px',
							anchor: '100%',
							autoScroll:true,
							listeners: {
								'resize': function(box) {
									//让滚动条始终保持在最下方
									var hwDom = box.getEl().dom;
									hwDom.scrollTop = hwDom.scrollHeight - hwDom.offsetHeight;
								}
							}
						}), 
						new parent.Ext.form.HtmlEditor({
							id: 'cw_iw_' + node.id,
							hideLabel: true,
							border: false,
							bodyStyle: 'padding:0px',
							name: 'htmleditor',
							height: 100,
							anchor: '100%',
							enableAlignments: false,//左、中、右对齐按钮
							enableLinks: false,//超连接按钮
							enableLists: false,//编号、项目按钮
							enableSourceEdit: false,//源代码编辑按钮
							listeners: {
								'initialize': function(edit) {
									//获取焦点
									edit.focus();
								}
							},
							fireSubmit: function(e) {
								if (e.ctrlKey && Ext.EventObject.ENTER == e.getKey()) {
									//alert(11);
								}
							}
						})
					]
				})
			],
			buttons: [{
				text: '清空',
				handler: function() {
					parent.Ext.get('cw_hw_' + node.id).dom.innerHTML = '';
				}
			},{
				text: '发送',
				handler: function() {
					//得到要发送的信息
					var smessage = parent.Ext.getCmp('cw_iw_'+ node.id).getValue();
					if(smessage == null || smessage == '') {
						var toolTip = new parent.Ext.ToolTip({
							target: 'mainUI',
							dismissDelay: 1500 ,
							html: '发送内容不能为空，请重新输入。'
						});
						toolTip.showAt([this.el.getX()-100, this.el.getY()-25]);
						return;
					}
					//替换回车符
					//smessage = encodeURIComponent(smessage.replace('<br>', node.id));
					//smessage = smessage.replace(/\<br\>/ig, node.id);
					smessage = encodeURIComponent(smessage.replace(/(\<br\>){2}$/ig, ''));//解决htmlEditor自动添加<br>
					//使用两次encodeURIComponent解决pushlet自动解码导致崩溃问题
					PL.publish('/user/chat', 'p_to='+ node.id+ '&message='+ encodeURIComponent(smessage));
					//得到当前时间
					var now = new Date()
					var time = " "+ now.getHours() +":"+ now.getMinutes() +":"+ now.getSeconds();
					//修改聊天历史框
					var ShowMessage = "<span style='color:green;font-weight:bold;font-size:12'>" + c_getUsername() 
							+ "</span><span style='color:green;'> " + '     ' + time + "</span>" + '<br/>' 
							+ parent.Ext.getCmp('cw_iw_'+ node.id).getValue() + '<br/>';
					parent.Ext.get('cw_hw_' + node.id).dom.innerHTML += ShowMessage;
					//Ext.get('cw_hw_' + node.id).dom.value += c_getUsername() + '  ' + time + ' \n'
					//        + Ext.get('cw_iw_' + node.id).dom.value + '\n\n';
					//清空输入框
					parent.Ext.getCmp('cw_iw_' + node.id).setValue('');
					//让滚动条始终保持在最下方
					var hwDom = parent.Ext.get('cw_hw_' + node.id).dom;
					hwDom.scrollTop = hwDom.scrollHeight - hwDom.offsetHeight;
				}
			}]

		});
	}
	chatwindow.show();
}
    </script>
	</head>

	<body onload="PL._init();">
		<div id="im"></div>
	</body>
</html>
